/**
  ******************************************************************************
  * @file    main.c
  * @author  Dynapack ADT, Hsinmo
  * @version V1.0.0
  * @date    3-April-2013
  * @brief   main
  ******************************************************************************
  * @attention
  *
  * DESCRIPTION....
  *
  * <h2><center>&copy; COPYRIGHT 2013 Dynapack</center></h2>
  ******************************************************************************
  */

//==============================================================================
// Includes
//==============================================================================
#include <intrinsics.h>
#include <string.h>

#include "Global_Vars_Define.h"
#include "Vars_Bit_Define.h"
#include "SystemConfigDefineForFlash.h"

#include "USB_config/descriptors.h"

#include "USB_API/USB_Common/device.h"
#include "USB_API/USB_Common/types.h"               //Basic Type declarations
#include "USB_API/USB_Common/usb.h"                 //USB-specific functions

#include "F5xx_F6xx_Core_Lib/HAL_UCS.h"
#include "F5xx_F6xx_Core_Lib/HAL_PMM.h"

#include "USB_API/USB_CDC_API/UsbCdc.h"
//#include "usbConstructs.h"

#include "gpio.h"

#include "MCU_Devices/MCU_Devices.h"
#include "DUI_For_USB_CDC.h"
#include "DUI_For_UART.h"
#include "DUI_For_Peripheral_Control.h"
//==============================================================================
// Global/Extern variables
//==============================================================================
//==============================================================================
// Extern functions
//==============================================================================
//==============================================================================
// Private typedef
//==============================================================================
//==============================================================================
// Private define
//==============================================================================
//#define _Debug_Disable_USB_Function_
//#define Auto_Check_Charger_result_Size  24
//==============================================================================
// Private macro
//==============================================================================
//==============================================================================
// Private Enum
//==============================================================================
//==============================================================================
// Private variables
//==============================================================================
unsigned int G_Var_Array[Global_VarArray_Int_Size];

//t_uint16 g_ADC_Result_data16[3];

//t_uint16 g_Auto_Check_Charger_result[Auto_Check_Charger_result_Size];
//==============================================================================
// Private function prototypes
//==============================================================================

//==============================================================================
// Private functions
//==============================================================================
void LED1_Test(){
    //Toggle P1.0
    //GPIO_toggleOutputOnPin( GPIO_PORT_P1, GPIO_PIN0 );
    GPIO_toggleOutputOnPin( GPIO_PORT_P2, GPIO_PIN6 );
    //GPIO_setOutputHighOnPin( GPIO_PORT_P1, GPIO_PIN0 );
    //GPIO_setOutputLowOnPin( GPIO_PORT_P1, GPIO_PIN0 );
}
void LED2_Test(){
    ////Toggle P8.1
    //GPIO_toggleOutputOnPin( GPIO_PORT_P8, GPIO_PIN1 );
    GPIO_toggleOutputOnPin( GPIO_PORT_P2, GPIO_PIN5 );
}
void LED3_Test(){
    //Toggle P8.2
    //GPIO_toggleOutputOnPin( GPIO_PORT_P8, GPIO_PIN2 );
    GPIO_toggleOutputOnPin( GPIO_PORT_P2, GPIO_PIN4 );
}
void PAD1_LED_Test(){
    //Toggle P1.1
    GPIO_toggleOutputOnPin( GPIO_PORT_P1, GPIO_PIN1 );
}
void PAD2_LED_Test(){
    //Toggle P1.2
    GPIO_toggleOutputOnPin( GPIO_PORT_P1, GPIO_PIN2 );
}
void PAD3_LED_Test(){
    //Toggle P1.3
    GPIO_toggleOutputOnPin( GPIO_PORT_P1, GPIO_PIN3 );
}
void PAD4_LED_Test(){
    //Toggle P1.4
    GPIO_toggleOutputOnPin( GPIO_PORT_P1, GPIO_PIN4 );
}
void PAD5_LED_Test(){
    //Toggle P1.5
    GPIO_toggleOutputOnPin( GPIO_PORT_P1, GPIO_PIN5 );
}



/*----------------------------------------------------------------------------+
 | Main Routine                                                                |
 +----------------------------------------------------------------------------*/
//            __delay_cycles(100);    //12us at 8MHz
//            __delay_cycles(1000);   //130us at 8MHz
//            __delay_cycles(2000);   //260us at 8MHz
//            __delay_cycles(3000);   //390us at 8MHz
//            __delay_cycles(5000);   //634us at 8MHz
//            __delay_cycles(10000);   //1260us at 8MHz


void main (void)
{

    WDTCTL = WDTPW + WDTHOLD;   //Stop watchdog timer

    _DUI_Init_IO_Ports();       //Init ports (do first ports because clocks do change ports)

    //////////////////////////////////////////////////////////
    // status init
    G_Module_Status = 0;
    G_Module_Function_Status = 0;


    _Device_Init_I2C_IO_Port_As_Input();
    if((_Device_get_SDA_Pin_Status() == IO_INPUT_LOW) && (_Device_get_SCL_Pin_Status() == IO_INPUT_HIGH)){
        G_Module_Status |= SetAsOnlyComPort;
    }else{
        G_Module_Status &= ~SetAsOnlyComPort;
    }
    //////////////////////////////////////////////////////////
    // direct call from device
    _Device_Set_Power_Management_Module();
    //_Device_Clock_Source_Set_Out_To_Pin();
    _Device_Init_Clock_Module();

    //while(1);

#if !defined(_Debug_Disable_USB_Function_)
    _DUI_Init_USB_AS_CDC_Communication();
#endif
    _DUI_Charger_Function_Init();


    _DUI_Init_Polling_Timer();


#if !defined(_Debug_Disable_USB_Function_)
    _DUI_Set_Function_To_Polling(_DUI_USB_CDC_Polling_Status_Function);
#endif

    _DUI_Set_Function_To_Polling(_DUI_Auto_check_Charger_for_Pollong);
    //_DUI_Set_Function_To_Polling(LED1_Test);

    //_DUI_Set_Function_To_Polling(LED2_Test);
    //_DUI_Set_Function_To_Polling(LED3_Test);
    _DUI_Start_Polling_Timer();

    _DUI_MUX_Init();
    _DUI_Init_Comm_Packet_Form_Detection_Timer();
    _DUI_Communication_Enable(Uart_RS485_Module);
    _DUI_Communication_Enable(One_Wire_Module);



    _DUI_Set_Charger_Channel(CHG_ON_Channel);

    __enable_interrupt();                           //Enable interrupts globally


    //t_uint8 count = 0;

    GPIO_setOutputLowOnPin( GPIO_PORT_P2, GPIO_PIN6 );
    GPIO_setOutputLowOnPin( GPIO_PORT_P2, GPIO_PIN5 );
    GPIO_setOutputLowOnPin( GPIO_PORT_P2, GPIO_PIN4 );
    while(1){
                //_NOP();
                //_NOP();
                //_NOP();
                //_NOP();

            //Delay
            //GPIO_setOutputLowOnPin( GPIO_PORT_P2, GPIO_PIN6 );
            //GPIO_setOutputHighOnPin( GPIO_PORT_P2, GPIO_PIN6 );
//            __delay_cycles(100);    //12us at 8MHz
//            __delay_cycles(1000);   //130us at 8MHz
//            __delay_cycles(2000);   //260us at 8MHz
//            __delay_cycles(3000);   //390us at 8MHz
//            __delay_cycles(5000);   //634us at 8MHz
//            __delay_cycles(10000);   //1260us at 8MHz


            //__delay_cycles(1000000);
#if !defined(_Debug_Disable_USB_Function_)
            __bis_SR_register(LPM0_bits);
            _DUI_USB_Main_Polling_Function_For_Parsing_Receiving_Packet();
#endif
            //LED2_Test();
            //_DUI_Set_Charger_Channel(CHG_ON_Channel);

    //float t_float;
    if(((G_Module_Function_Status & ADC_Start_Conversion)==0) && ((G_Module_Function_Status & ADC_Done_Conversion)==0)){
        GPIO_setOutputHighOnPin( GPIO_PORT_P2, GPIO_PIN6 );
        GPIO_setOutputHighOnPin( GPIO_PORT_P2, GPIO_PIN5 );
        _DUI_Start_ADC_Conversion();
        GPIO_setOutputLowOnPin( GPIO_PORT_P2, GPIO_PIN5 );
    }else if(G_Module_Function_Status & ADC_Done_Conversion){
        GPIO_setOutputHighOnPin( GPIO_PORT_P2, GPIO_PIN4 );

        G_Charger_48V_Channel_ADC = _DUI_Channle_ADC_Result(ADC_48V_Channel);
        G_Charger_36V_Channel_ADC = _DUI_Channle_ADC_Result(ADC_36V_Channel);
        G_Charger_24V_Channel_ADC = _DUI_Channle_ADC_Result(ADC_24V_Channel);
        G_BatteryV_Channel_ADC = _DUI_Channle_ADC_Result(ADC_BatteryV_Channel);

//        t_float = FA_24V_mV_To_ADC_Factor;
//        t_float = G_Charger_24V_Channel_ADC/t_float;
//        g_Voltage_Result_data16[2] = (unsigned int)t_float;
//
//        t_float = FA_36V_mV_To_ADC_Factor;
//        t_float = G_Charger_36V_Channel_ADC/t_float;
//        g_Voltage_Result_data16[1] = (unsigned int)t_float;
//
//        t_float = FA_48V_mV_To_ADC_Factor;
//        t_float = G_Charger_48V_Channel_ADC/t_float;
//        g_Voltage_Result_data16[0] = (unsigned int)t_float;


        G_Module_Function_Status &= ~ADC_Done_Conversion;
        G_Module_Function_Status &= ~ADC_Start_Conversion;

        GPIO_setOutputLowOnPin( GPIO_PORT_P2, GPIO_PIN6 );
        GPIO_setOutputLowOnPin( GPIO_PORT_P2, GPIO_PIN4 );
    }
//    /////////////////////////////////////////////////////////////////////////////////////
//    //serial Steps for auto check charger
//    if(G_Module_Function_Status & Charger_Check_48V_ID_Ch){
//        //after 100 ms
//        g_Auto_Check_Charger_result[10] = G_Charger_48V_Channel_ADC;
//        g_Auto_Check_Charger_result[11] = _DUI_Get_Voltage_By_ADC(ADC_48V_Channel, G_Charger_48V_Channel_ADC);
//        _DUI_Set_Charger_ID(CHG_36V_Channel);
//        G_Module_Function_Status &= ~Charger_Check_48V_ID_Ch;
//        G_Module_Function_Status |= Charger_Check_Done;
//    }
//    if(G_Module_Function_Status & Charger_Check_36V_ID_Ch){
//        //after 100 ms
//        g_Auto_Check_Charger_result[8] = G_Charger_36V_Channel_ADC;
//        g_Auto_Check_Charger_result[9] = _DUI_Get_Voltage_By_ADC(ADC_36V_Channel, G_Charger_36V_Channel_ADC);
//        _DUI_Set_Charger_ID(CHG_36V_Channel);
//        G_Module_Function_Status &= ~Charger_Check_36V_ID_Ch;
//        G_Module_Function_Status |= Charger_Check_48V_ID_Ch;
//    }
//    if(G_Module_Function_Status & Charger_Check_24V_ID_Ch){
//        //after 100 ms
//        g_Auto_Check_Charger_result[6] = G_Charger_24V_Channel_ADC;
//        g_Auto_Check_Charger_result[7] = _DUI_Get_Voltage_By_ADC(ADC_24V_Channel, G_Charger_24V_Channel_ADC);
//        _DUI_Set_Charger_ID(CHG_36V_Channel);
//        G_Module_Function_Status &= ~Charger_Check_24V_ID_Ch;
//        G_Module_Function_Status |= Charger_Check_36V_ID_Ch;
//    }
//    if(G_Module_Function_Status & Charger_Check_OFF_ID_Ch){
//        //after 100 ms
//        g_Auto_Check_Charger_result[0] = G_Charger_24V_Channel_ADC;
//        g_Auto_Check_Charger_result[1] = _DUI_Get_Voltage_By_ADC(ADC_24V_Channel, G_Charger_24V_Channel_ADC);
//        g_Auto_Check_Charger_result[2] = G_Charger_36V_Channel_ADC;
//        g_Auto_Check_Charger_result[3] = _DUI_Get_Voltage_By_ADC(ADC_36V_Channel, G_Charger_36V_Channel_ADC);
//        g_Auto_Check_Charger_result[4] = G_Charger_48V_Channel_ADC;
//        g_Auto_Check_Charger_result[5] = _DUI_Get_Voltage_By_ADC(ADC_48V_Channel, G_Charger_48V_Channel_ADC);
//        _DUI_Set_Charger_ID(CHG_24V_Channel);
//        G_Module_Function_Status &= ~Charger_Check_OFF_ID_Ch;
//        G_Module_Function_Status |= Charger_Check_24V_ID_Ch;
//    }
//    if(G_Module_Function_Status & Start_Charger_Check){
//        G_Module_Function_Status |= Charger_Check_Actived;
//        _DUI_Set_Charger_Channel(CHG_ON_Channel);
//        _DUI_Set_Charger_ID(CHG_OFF_Channel);
//        G_Module_Function_Status &= ~Start_Charger_Check;
//        G_Module_Function_Status |= Charger_Check_OFF_ID_Ch;
//    }
//    //last Done
//    if(G_Module_Function_Status & Charger_Check_Done){
//        //
//        _DUI_CDC_Transmitting_Data_With_USB_Protocol_Packet(0xA6,(t_uint8 *)g_Auto_Check_Charger_result, Auto_Check_Charger_result_Size);
//        _DUI_Set_Charger_ID(CHG_OFF_Channel);
//        G_Module_Function_Status &= ~Charger_Check_Done;
//        G_Module_Function_Status &= ~Charger_Check_Actived;
//    }


            //__delay_cycles(100);
            //_DUI_Set_Charger_Channel(CHG_36V_Channel);
            //_DUI_Start_ADC_Conversion();
            //__delay_cycles(10000);
            //g_ADC_Result_data16[0] = _DUI_Channle_ADC_Result(ADC_Channel0);
            //g_ADC_Result_data16[1] = _DUI_Channle_ADC_Result(ADC_Channel1);
            //g_ADC_Result_data16[2] = _DUI_Channle_ADC_Result(ADC_Channel2);
            //__delay_cycles(10000);
            //__delay_cycles(10000);

            //sst = _Device_I2C_Master_Write_Bytes(TransmitCMD,1);
            //sst = _Device_I2C_Master_Read_Bytes(TransmitData,2);

            //__delay_cycles(1000000);


            //_DUI_Communication_Send_Bytes(Uart_RS485_Module, tdata,8);



//            if(count == 10){
//                _DUI_Remove_Function_Out_Of_Polling(LED2_Test);
//            }else if(count == 20){
//                _DUI_Remove_Function_Out_Of_Polling(LED1_Test);
//            }else if(count == 30){
//                _DUI_Remove_Function_Out_Of_Polling(LED3_Test);
//            }else if(count == 40){
//                _DUI_Set_Function_To_Polling(LED3_Test);
//            }
//            if(count > 60){
//                count = 0;
//            }else{
//                count++;
//            }

            //sst = _Device_I2C_Master_Write_Bytes(TransmitCMD,1);
            //sst = _Device_I2C_Master_Read_Bytes(TransmitData,2);
        //_Device_I2C_Master_Write();
        //_Device_I2C_Master_Read();
            //LED2_Test();
    }


}                               //main()
/*
 * ======== Init_Clock ========
 */
//VOID Init_Clock (VOID)
//{
//    //Initialization of clock module
//    if (USB_PLL_XT == 2){
//		#if defined (__MSP430F552x) || defined (__MSP430F550x)
//			P5SEL |= 0x0C;                                      //enable XT2 pins for F5529
//		#elif defined (__MSP430F563x_F663x)
//			P7SEL |= 0x0C;
//		#endif
//
//        //use REFO for FLL and ACLK
//        UCSCTL3 = (UCSCTL3 & ~(SELREF_7)) | (SELREF__REFOCLK);
//        UCSCTL4 = (UCSCTL4 & ~(SELA_7)) | (SELA__REFOCLK);
//
//        //MCLK will be driven by the FLL (not by XT2), referenced to the REFO
//        Init_FLL_Settle(USB_MCLK_FREQ / 1000, USB_MCLK_FREQ / 32768);   //Start the FLL, at the freq indicated by the config
//                                                                        //constant USB_MCLK_FREQ
//        XT2_Start(XT2DRIVE_0);                                          //Start the "USB crystal"
//    }
//	else {
//		#if defined (__MSP430F552x) || defined (__MSP430F550x)
//			P5SEL |= 0x10;                                      //enable XT1 pins
//		#endif
//        //Use the REFO oscillator to source the FLL and ACLK
//        UCSCTL3 = SELREF__REFOCLK;
//        UCSCTL4 = (UCSCTL4 & ~(SELA_7)) | (SELA__REFOCLK);
//
//        //MCLK will be driven by the FLL (not by XT2), referenced to the REFO
//        Init_FLL_Settle(USB_MCLK_FREQ / 1000, USB_MCLK_FREQ / 32768);   //set FLL (DCOCLK)
//
//        XT1_Start(XT1DRIVE_0);                                          //Start the "USB crystal"
//    }
//}
//


/*
 * ======== UNMI_ISR ========
 */
#pragma vector = UNMI_VECTOR
__interrupt VOID UNMI_ISR (VOID)
{
    switch (__even_in_range(SYSUNIV, SYSUNIV_BUSIFG ))
    {
        case SYSUNIV_NONE:
            __no_operation();
            break;
        case SYSUNIV_NMIIFG:
            __no_operation();
            break;
        case SYSUNIV_OFIFG:
            UCSCTL7 &= ~(DCOFFG + XT1LFOFFG + XT2OFFG); //Clear OSC flaut Flags fault flags
            SFRIFG1 &= ~OFIFG;                          //Clear OFIFG fault flag
            break;
        case SYSUNIV_ACCVIFG:
            __no_operation();
            break;
        case SYSUNIV_BUSIFG:
            SYSBERRIV = 0;                                      //clear bus error flag
            USB_disable();                                      //Disable
    }
}

